<?php
namespace Common\Model;

class RechargeModel extends Model {
    protected $tableName = 'recharge';

    /**
     * buildSearchExpr 
     * 组装查询条件
     * 
     * @param mixed $d  查询数据，一般来源于$_GET或$_POST
     * @param mixed $field  可查询的字段对照表，其结构为array(array('表单项目名称' => '数据库字段名称'))
     * @access public
     * @return void 返回值为数组，参见方法内部注释
     */
    public function buildSearchExpr($d, $field = NULL) {
        $expr = array();
        $dao  = array();
        $sortExpr = $this->pk . ' DESC';

        /**
         * 下标为表单中的项目名称，值为数据库中表的字段名称 
         */
        if(empty($field)) {
            $field = [                
                'user_name'   => 'user_name',
                'status'      => 'status',
                'finish_date' => 'finish_time',
                'user_type'   => 'user_type',
                'type'        => 'type',
            ];
        }

        foreach($field as $k => $v) {
            $val     = isset($d[$k]) ? trim($d[$k]) : '';
            $tmpExpr = '';

            if(strlen($val) < 1) {
                continue;
           }

            switch($k) {
                case 'user_name' :
                    $expr[$v] = array('EXP', "LIKE '%{$val}%'");
                    break;

                case 'finish_date' : 
                    $val = date('Y-m-d', strtotime($val));
                    $tmpExpr = "to_char(finish_time, 'YYYY-MM-DD')='{$val}'";
                    break;

                default:
                    $expr[$v] = $d[$k];
            }

            if($tmpExpr) {
                $expr['_string'] = empty($expr['_string']) ? $tmpExpr : $expr['_string'] . " AND ($tmpExpr)";
            }

            $dao[$k] = $d[$k];
        }

        /**
         * 处理多个查询项目合并到一起，然后只能选一项查询的情况
         * 保存到$dao中，用于回填至查询表单
         */
        foreach($d as $k => $v) {
            if(substr($k, 0, 12) == 'search_item_') {
                $dao[$k] = $v;
            }
        }

        /**
         * 因为部分查询会涉及到视图，所以需要在下面指定完整的可排序字段
         */
        $sortField = array('r_id', 'uid', 'user_name', 'r_comment', 'r_status', 'user_type', 'r_create_time', 'r_finish_time');

        if(!empty($d['sort']) && in_array($d['sort'], $sortField)) {
            $sortdir = empty($d['sortdir'])                     ? 'DESC'   : strtoupper($d['sortdir']);
            $sortdir = in_array($sortdir, array('DESC', 'ASC')) ? $sortdir : 'DESC';

            $sort     = $d['sort'];
            $sortExpr = "{$sort} {$sortdir}";

            $dao['sort']    = $sort;
            $dao['sortdir'] = $sortdir;
        }

        return array(
            'expr' => $expr,            //ThinkPHP查询条件表达式
            'sort' => $sortExpr,        //排序表达式
            'json' => json_encode($dao) //用于回填至查询表单的数据
        );
    }

    public function save2($d) {
        $userName = empty($d['user_name']) ? '' : $d['user_name'];

        if(empty($userName)) {
            throw new \Exception('没有会员名称，无法充值');
        }

        $userModel = D('User');

        if(!$userRecord = $userModel->getByName($userName)) {
            throw new \Exception('没有找到会员数据');
        }

        $moneyField = 'money_1';
        $d['uid']   = $userRecord['id'];

        /**
         * type=1表示站长
         */
        if($userRecord['type'] == 1) {
            if (empty($d['money_type'])) {
                throw new \Exception('请指定充值接收的对象，日余额、周余额、还是月余额？');
            }

            $d['money_type'] = (int)($d['money_type']);

            if(!array_key_exists($d['money_type'], C('CLEARING_TYPES'))) {
                throw new \Exception('充值对象有误');
            }

            $moneyField = 'money_' . $d['money_type'];
        }

        if($userRecord['type'] != 2 && $d['type'] == 3) {
            throw new \Exception('只有广告主才能预充');
        }

        $d['money'] = empty($d['money']) ? 0 : (float)$d['money'];

        if(empty($d['money'])) {
            throw new \Exception('请指定充值金额');
        }

        /**
         * 1表示增加，2表示扣除，3表示预充
         */
        if (empty($d['type']) || !array_key_exists($d['type'], C('RECHARGE_TYPES'))) {
            throw new \Exception('充值方式有误');
        }

        $d['create_time'] = date('Y-m-d H:i:s');
        $d['finish_time'] = $d['create_time'];
        $d['gateway']     = empty($d['gateway']) ? C('RECHARGE_DEFAULT_GATEWAY') : $d['gateway'];
        $d['operator']    = C('RUN_LOGIN_USER.name');

        $this->startTrans();

        if (!$this->add($d)) {
            $this->rollback();

            throw new \Exception('充值数据保存出错');
        }

        $action = $d['type'] == 2 ? 'setDec' : 'setInc';
        $expr   = ['id' => $userRecord['id']];

        if(!$_r = $userModel->where($expr)->$action($moneyField, $d['money'])) {
            $this->rollback();

            throw new \Exception('更新会员余额出错');
        }

        $this->commit();

        /*
        if($rUser['type'] == 2) {
            try {
                cacheApi('aderRecharge', $rUser['uid']);
            } catch(\Exception $e) {
                throw new Exception($e->getMessage());
            }
        }
         */

        return true;
    }

    /**
     * saveDeduction
     * 针对预充值的扣除操作
     *
     * 只有广告主才会存在预充值
     * 
     * 会有以下操作：
     * 1.增加与预充值记录数据相同的扣除记录
     * 2.将预充值记录状态改成预充值已被扣除
     * 3.减少会员余额
     *
     * @param mixed $d
     * @return void
     */
    public function saveDeduction($d) {
        $id = empty($d['id']) ? 0 : (int)$d['id'];

        if (empty($id)) {
            throw new \Exception('参数不完整，无法保存数据');
        }

        if (!$record = $this->where(['id' => $id])->find()) {
            throw new \Exception('没有找到预充值记录');
        }

        $userModel = D('User');

        if (!$userRecord = $userModel->where(['id' => $record['uid']])->find()) {
            throw new \Exception('没有找到会员信息');
        }

        if ($record['status'] != 3) {
            throw new \Exception('不是预充值记录，不能被扣除');
        }

        $d['comment'] = empty($r['comment']) ? '' : trim($d['comment']);

        if (empty($d['comment'])) {
            $d['comment'] = "扣除{$record['finish_time']}预充的{$record['money']}元。";
        }

        $time = date('Y-m-d H:i:s');
        $dao  = [
            'uid'         => $record['uid'],
            'money'       => $record['money'],
            'money_type'  => $record['money_type'],
            'type'        => 2, //2表示扣除
            'create_time' => $time,
            'finish_time' => $time,
            'comment'     => $d['comment'],
            'gateway'     => C('RECHARGE_DEFAULT_GATEWAY'),
            'operator'    => C('RUN_LOGIN_USER.name'),
        ];

        $this->startTrans();

        try {
            if (!$this->add($dao)) {
                throw new \Exception('保存扣除数据出错');
            }

            if (!$this->where(['id' => $id])->save(['type' => 4])) {
                throw new \Exception('更改预充值状态出错');
            }

            if (!$userModel->where(['id' => $dao['uid']])->setDec('money_1', $record['money'])) {
                throw new \Exception('扣除会员余额出错');
            }
        } catch(\Exception $e) {
            $this->rollback();

            throw new \Exception($e->getMessage());
        }

        $this->commit();

        return true;
    }

    protected function _options_filter(&$options) {
        if(ACTION_NAME == 'addCallback') {
            return true;
        }

        if(!$loginUser = C('RUN_LOGIN_USER')) {
            exit('NO LOGIN');
        }

        /**
         * 为广告主平台数据绑定广告主编号
         */
        if($loginUser['type'] == 2) {
            $options['where']        = isset($options['where']) ? $options['where'] : array();
            $options['where']['uid'] = $loginUser['id'];

            return true;
        }

    }

}
